#include "qtquick2applicationviewer.h"
#include "smartingeegclientagent.h"
#include "plot.h"
#include "qcustomplot.h"
#include "signalprocessing/signalprocessing.h"
#include "signalprocessing/sampler/decimator.h"

#include <QApplication>
#include <QQmlContext>
#include <QtQml>
#include <QtQuick/QQuickView>

class TestOSignal : public OSignal
{
    int time = 0;
    float w = 0.05;

public:
    TestOSignal() : OSignal(0)
    {
    }

    bool onBurstRequest(size_t burstLength)
    {
        for(size_t i = 0; i < burstLength; ++i)
        {
            (*this)[0] = sin(2 * 3.14 * w * time++);
            writeOutSample();

            //QThread::msleep(1);
        }

        return true;
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    TestOSignal *testOSignal = new TestOSignal;

    SmartingEEGClientAgent::registerTypes("SmartingEEGClientAgent");
    qmlRegisterType<Plot>("CustomPlot", 1, 0, "Plot");

    QQmlApplicationEngine engine;
    engine.load(QUrl("qrc:/qml/SmartingEEGClient/MainPage.qml"));
    QObject *topLevel = engine.rootObjects().value(0);
    QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
    if ( !window ) {
        qWarning("Error: Your root item has to be a Window.");
        return -1;
    }

/*    SmartingEEGClientAgent *eegAgent = window->findChild<SmartingEEGClientAgent *>("eegAgent");

    Plot *channel00Plot = window->findChild<Plot *>("channel00Plot");
    Plot *channel01Plot = window->findChild<Plot *>("channel01Plot");
    Plot *channel02Plot = window->findChild<Plot *>("channel02Plot");
    Plot *channel03Plot = window->findChild<Plot *>("channel03Plot");
    Plot *channel04Plot = window->findChild<Plot *>("channel04Plot");
    Plot *channel05Plot = window->findChild<Plot *>("channel05Plot");
    Plot *channel06Plot = window->findChild<Plot *>("channel06Plot");
    Plot *channel07Plot = window->findChild<Plot *>("channel07Plot");
    Plot *channel08Plot = window->findChild<Plot *>("channel08Plot");
    Plot *channel09Plot = window->findChild<Plot *>("channel09Plot");
    Plot *channel10Plot = window->findChild<Plot *>("channel10Plot");
    Plot *channel11Plot = window->findChild<Plot *>("channel11Plot");
    Plot *channel12Plot = window->findChild<Plot *>("channel12Plot");
    Plot *channel13Plot = window->findChild<Plot *>("channel13Plot");
    Plot *channel14Plot = window->findChild<Plot *>("channel14Plot");
    Plot *channel15Plot = window->findChild<Plot *>("channel15Plot");
    Plot *channel16Plot = window->findChild<Plot *>("channel16Plot");
    Plot *channel17Plot = window->findChild<Plot *>("channel17Plot");
    Plot *channel18Plot = window->findChild<Plot *>("channel18Plot");
    Plot *channel19Plot = window->findChild<Plot *>("channel19Plot");
    Plot *channel20Plot = window->findChild<Plot *>("channel20Plot");
    Plot *channel21Plot = window->findChild<Plot *>("channel21Plot");
    Plot *channel22Plot = window->findChild<Plot *>("channel22Plot");
    Plot *channel23Plot = window->findChild<Plot *>("channel23Plot");

    Plot *syncPlot = window->findChild<Plot *>("syncPlot");
    Plot *gyroXPlot = window->findChild<Plot *>("gyroXPlot");
    Plot *gyroYPlot = window->findChild<Plot *>("gyroYPlot");
    Plot *gyroZPlot = window->findChild<Plot *>("gyroZPlot");
    Plot *batteryPlot = window->findChild<Plot *>("batteryPlot");

    Decimator *channel00Decimator = new Decimator(10, 100);
    Decimator *channel01Decimator = new Decimator(10, 100);
    Decimator *channel02Decimator = new Decimator(10, 100);
    Decimator *channel03Decimator = new Decimator(10, 100);
    Decimator *channel04Decimator = new Decimator(10, 100);
    Decimator *channel05Decimator = new Decimator(10, 100);
    Decimator *channel06Decimator = new Decimator(10, 100);
    Decimator *channel07Decimator = new Decimator(10, 100);
    Decimator *channel08Decimator = new Decimator(10, 100);
    Decimator *channel09Decimator = new Decimator(10, 100);
    Decimator *channel10Decimator = new Decimator(10, 100);
    Decimator *channel11Decimator = new Decimator(10, 100);
    Decimator *channel12Decimator = new Decimator(10, 100);
    Decimator *channel13Decimator = new Decimator(10, 100);
    Decimator *channel14Decimator = new Decimator(10, 100);
    Decimator *channel15Decimator = new Decimator(10, 100);
    Decimator *channel16Decimator = new Decimator(10, 100);
    Decimator *channel17Decimator = new Decimator(10, 100);
    Decimator *channel18Decimator = new Decimator(10, 100);
    Decimator *channel19Decimator = new Decimator(10, 100);
    Decimator *channel20Decimator = new Decimator(10, 100);
    Decimator *channel21Decimator = new Decimator(10, 100);
    Decimator *channel22Decimator = new Decimator(10, 100);
    Decimator *channel23Decimator = new Decimator(10, 100);

    Decimator *syncDecimator = new Decimator(10, 100);
    Decimator *gyroXDecimator = new Decimator(10, 100);
    Decimator *gyroYDecimator = new Decimator(10, 100);
    Decimator *gyroZDecimator = new Decimator(10, 100);
    Decimator *batteryDecimator = new Decimator(10, 100);

    eegAgent->init();

    channel00Plot->init();
    channel01Plot->init();
    channel02Plot->init();
    channel03Plot->init();
    channel04Plot->init();
    channel05Plot->init();
    channel06Plot->init();
    channel07Plot->init();
    channel08Plot->init();
    channel09Plot->init();
    channel10Plot->init();
    channel11Plot->init();
    channel12Plot->init();
    channel13Plot->init();
    channel14Plot->init();
    channel15Plot->init();
    channel16Plot->init();
    channel17Plot->init();
    channel18Plot->init();
    channel19Plot->init();
    channel20Plot->init();
    channel21Plot->init();
    channel22Plot->init();
    channel23Plot->init();

    syncPlot->init();
    gyroXPlot->init();
    gyroYPlot->init();
    gyroZPlot->init();
    batteryPlot->init();

    SignalConnection::connect(eegAgent->getChannel00OSignal(), *channel00Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel01OSignal(), *channel01Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel02OSignal(), *channel02Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel03OSignal(), *channel03Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel04OSignal(), *channel04Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel05OSignal(), *channel05Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel06OSignal(), *channel06Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel07OSignal(), *channel07Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel08OSignal(), *channel08Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel09OSignal(), *channel09Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel10OSignal(), *channel10Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel11OSignal(), *channel11Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel12OSignal(), *channel12Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel13OSignal(), *channel13Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel14OSignal(), *channel14Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel15OSignal(), *channel15Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel16OSignal(), *channel16Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel17OSignal(), *channel17Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel18OSignal(), *channel18Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel19OSignal(), *channel19Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel20OSignal(), *channel20Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel21OSignal(), *channel21Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel22OSignal(), *channel22Decimator->getInputSignal());
    SignalConnection::connect(eegAgent->getChannel23OSignal(), *channel23Decimator->getInputSignal());

    SignalConnection::connect(eegAgent->getSyncOSignal(), *syncDecimator->getInputSignal());
    SignalConnection::connect(eegAgent->getGyroXOSignal(), *gyroXDecimator->getInputSignal());
    SignalConnection::connect(eegAgent->getGyroYOSignal(), *gyroYDecimator->getInputSignal());
    SignalConnection::connect(eegAgent->getGyroZOSignal(), *gyroZDecimator->getInputSignal());
    SignalConnection::connect(eegAgent->getBatteryOSignal(), *batteryDecimator->getInputSignal());

    SignalConnection::connect(*channel00Decimator->getOutputSignal(), channel00Plot->getISignal());
    SignalConnection::connect(*channel01Decimator->getOutputSignal(), channel01Plot->getISignal());
    SignalConnection::connect(*channel02Decimator->getOutputSignal(), channel02Plot->getISignal());
    SignalConnection::connect(*channel03Decimator->getOutputSignal(), channel03Plot->getISignal());
    SignalConnection::connect(*channel04Decimator->getOutputSignal(), channel04Plot->getISignal());
    SignalConnection::connect(*channel05Decimator->getOutputSignal(), channel05Plot->getISignal());
    SignalConnection::connect(*channel06Decimator->getOutputSignal(), channel06Plot->getISignal());
    SignalConnection::connect(*channel07Decimator->getOutputSignal(), channel07Plot->getISignal());
    SignalConnection::connect(*channel08Decimator->getOutputSignal(), channel08Plot->getISignal());
    SignalConnection::connect(*channel09Decimator->getOutputSignal(), channel09Plot->getISignal());
    SignalConnection::connect(*channel10Decimator->getOutputSignal(), channel10Plot->getISignal());
    SignalConnection::connect(*channel11Decimator->getOutputSignal(), channel11Plot->getISignal());
    SignalConnection::connect(*channel12Decimator->getOutputSignal(), channel12Plot->getISignal());
    SignalConnection::connect(*channel13Decimator->getOutputSignal(), channel13Plot->getISignal());
    SignalConnection::connect(*channel14Decimator->getOutputSignal(), channel14Plot->getISignal());
    SignalConnection::connect(*channel15Decimator->getOutputSignal(), channel15Plot->getISignal());
    SignalConnection::connect(*channel16Decimator->getOutputSignal(), channel16Plot->getISignal());
    SignalConnection::connect(*channel17Decimator->getOutputSignal(), channel17Plot->getISignal());
    SignalConnection::connect(*channel18Decimator->getOutputSignal(), channel18Plot->getISignal());
    SignalConnection::connect(*channel19Decimator->getOutputSignal(), channel19Plot->getISignal());
    SignalConnection::connect(*channel20Decimator->getOutputSignal(), channel20Plot->getISignal());
    SignalConnection::connect(*channel21Decimator->getOutputSignal(), channel21Plot->getISignal());
    SignalConnection::connect(*channel22Decimator->getOutputSignal(), channel22Plot->getISignal());
    SignalConnection::connect(*channel23Decimator->getOutputSignal(), channel23Plot->getISignal());

    SignalConnection::connect(*syncDecimator->getOutputSignal(), syncPlot->getISignal());
    SignalConnection::connect(*gyroXDecimator->getOutputSignal(), gyroXPlot->getISignal());
    SignalConnection::connect(*gyroYDecimator->getOutputSignal(), gyroYPlot->getISignal());
    SignalConnection::connect(*gyroZDecimator->getOutputSignal(), gyroZPlot->getISignal());
    SignalConnection::connect(*batteryDecimator->getOutputSignal(), batteryPlot->getISignal());

    //eegAgent->start(); //TODO
    channel00Plot->start();
    channel01Plot->start();
    channel02Plot->start();
    channel03Plot->start();
    channel04Plot->start();
    channel05Plot->start();
    channel06Plot->start();
    channel07Plot->start();
    channel08Plot->start();
    channel09Plot->start();
    channel10Plot->start();
    channel11Plot->start();
    channel12Plot->start();
    channel13Plot->start();
    channel14Plot->start();
    channel15Plot->start();
    channel16Plot->start();
    channel17Plot->start();
    channel18Plot->start();
    channel19Plot->start();
    channel20Plot->start();
    channel21Plot->start();
    channel22Plot->start();
    channel23Plot->start();

    syncPlot->start();
    gyroXPlot->start();
    gyroYPlot->start();
    gyroZPlot->start();
    batteryPlot->start();*/

    window->show();
    return app.exec();
}
